package com.campus.secondhand.service.impl;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.secondhand.common.exception.BadRequestException;
import com.campus.secondhand.common.exception.ForbiddenException;
import com.campus.secondhand.common.exception.ResourceNotFoundException;
import com.campus.secondhand.model.dto.OrderCreateDTO;
import com.campus.secondhand.model.dto.OrderReviewDTO;
import com.campus.secondhand.entity.Order;
import com.campus.secondhand.entity.OrderReview;
import com.campus.secondhand.entity.Product;
import com.campus.secondhand.entity.ProductImages;
import com.campus.secondhand.entity.User;
import com.campus.secondhand.mapper.OrderMapper;
import com.campus.secondhand.mapper.OrderReviewMapper;
import com.campus.secondhand.mapper.ProductImageMapper;
import com.campus.secondhand.mapper.ProductMapper;
import com.campus.secondhand.mapper.UserMapper;
import com.campus.secondhand.service.OrderService;
import com.campus.secondhand.model.vo.OrderVO;

import lombok.extern.slf4j.Slf4j;

@Service
@Transactional
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderReviewMapper orderReviewMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProductImageMapper productImageMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // Redis缓存键常量
    private static final String CACHE_ORDER_PREFIX = "order:";
    private static final String CACHE_ORDER_BUYER_PREFIX = "order:buyer:";
    private static final String CACHE_ORDER_SELLER_PREFIX = "order:seller:";
    private static final String CACHE_ORDER_REVIEW_PREFIX = "order:review:";
    private static final long CACHE_ORDER_EXPIRE = 30; // 缓存过期时间，单位分钟

    @Override
    public Order createOrder(OrderCreateDTO orderDTO) {
        // 检查商品是否存在且可用
        Product product = productMapper.selectById(orderDTO.getProductId());
        if (product == null) {
            throw new ResourceNotFoundException("商品不存在");
        }

        if (product.getStatus() != 1) {
            throw new BadRequestException("商品已下架或已售出");
        }

        // 检查卖家是否存在
        User seller = userMapper.selectById(product.getSellerId());
        if (seller == null) {
            throw new ResourceNotFoundException("卖家不存在");
        }

        // 创建新订单
        Order order = new Order();
        order.setOrderNo(generateOrderNo());
        order.setBuyerId(orderDTO.getBuyerId());
        order.setSellerId(product.getSellerId());
        order.setProductId(product.getId());
        order.setPrice(product.getPrice());
        // 直接设置为待交易状态，因为是线下交易
        order.setStatus(1); // 状态1表示待交易
        order.setPaymentMethod(orderDTO.getPaymentMethod());
        order.setTransactionLocation(orderDTO.getTransactionLocation()); // 设置交易地点
        order.setPaymentTime(LocalDateTime.now());
        order.setRemark(orderDTO.getRemark());
        order.setCreatedAt(LocalDateTime.now());
        order.setUpdatedAt(LocalDateTime.now());
        order.setIsReviewed(false);

        // 保存订单
        orderMapper.insert(order);

        // 更新商品状态为已售出
        product.setStatus(2); // 假设2表示已售出
        productMapper.updateById(product);

        // 清除买家和卖家的订单缓存
        clearBuyerOrdersCache(orderDTO.getBuyerId());
        clearSellerOrdersCache(product.getSellerId());

        return order;
    }

    @Override
    public Page<OrderVO> getBuyerOrders(Long userId, Integer status, int page, int size) {
        // 构建缓存键
        String cacheKey = CACHE_ORDER_BUYER_PREFIX + userId + ":status:" + (status != null ? status : "all")
                + ":page:" + page + ":size:" + size;

        // 尝试从缓存获取
        Object cachedOrders = redisTemplate.opsForValue().get(cacheKey);
        if (cachedOrders != null) {
            log.info("从缓存获取买家订单数据: {}", cacheKey);
            return (Page<OrderVO>) cachedOrders;
        }

        Page<Order> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();

        // 买家订单查询条件
        queryWrapper.eq(Order::getBuyerId, userId);
        if (status != null) {
            queryWrapper.eq(Order::getStatus, status);
        }
        queryWrapper.orderByDesc(Order::getCreatedAt);

        IPage<Order> resultPage = orderMapper.selectPage(pageParam, queryWrapper);

        // 转换为OrderVO列表
        List<OrderVO> orderVOList = resultPage.getRecords().stream()
                .map(order -> {
                    OrderVO vo = OrderVO.fromOrder(order);

                    // 获取商品信息
                    Product product = productMapper.selectById(order.getProductId());
                    if (product != null) {
                        vo.setProductName(product.getName());

                        // 从商品图片表获取主图
                        LambdaQueryWrapper<ProductImages> imageQueryWrapper = new LambdaQueryWrapper<>();
                        imageQueryWrapper.eq(ProductImages::getProductId, product.getId())
                                .eq(ProductImages::getIsMain, 1) // 获取主图（isMain=1）
                                .or()
                                .eq(ProductImages::getProductId, product.getId())
                                .orderByAsc(ProductImages::getSortOrder) // 如果没有主图，获取排序最靠前的图片
                                .last("LIMIT 1"); // 只获取一张图片

                        ProductImages mainImage = productImageMapper.selectOne(imageQueryWrapper);
                        if (mainImage != null) {
                            vo.setProductImageUrl(mainImage.getImageUrl());
                        }
                    }

                    // 获取卖家信息
                    User seller = userMapper.selectById(order.getSellerId());
                    if (seller != null) {
                        vo.setSellerName(seller.getNickname());
                        vo.setSellerAvatar(seller.getAvatar());
                    }

                    // 获取评价信息
                    LambdaQueryWrapper<OrderReview> reviewQueryWrapper = new LambdaQueryWrapper<>();
                    reviewQueryWrapper.eq(OrderReview::getOrderId, order.getId());
                    OrderReview review = orderReviewMapper.selectOne(reviewQueryWrapper);

                    // 设置买家评价
                    if (review != null && review.getBuyerId().equals(userId)) {
                        vo.setBuyerReview(OrderVO.OrderReviewVO.fromOrderReview(review));
                    }

                    // 设置卖家评价（由于当前系统可能只有买家评价，这里提供一个空的评价）
                    vo.setSellerReview(null); // 默认暂无卖家评价

                    return vo;
                })
                .collect(Collectors.toList());

        Page<OrderVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
        voPage.setRecords(orderVOList);

        // 保存到缓存
        redisTemplate.opsForValue().set(cacheKey, voPage, CACHE_ORDER_EXPIRE, TimeUnit.MINUTES);

        return voPage;
    }

    @Override
    public Page<OrderVO> getSellerOrders(Long userId, Integer status, int page, int size) {
        // 构建缓存键
        String cacheKey = CACHE_ORDER_SELLER_PREFIX + userId + ":status:" + (status != null ? status : "all")
                + ":page:" + page + ":size:" + size;

        // 尝试从缓存获取
        Object cachedOrders = redisTemplate.opsForValue().get(cacheKey);
        if (cachedOrders != null) {
            log.info("从缓存获取卖家订单数据: {}", cacheKey);
            return (Page<OrderVO>) cachedOrders;
        }

        Page<Order> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();

        // 卖家订单查询条件
        queryWrapper.eq(Order::getSellerId, userId);
        if (status != null) {
            queryWrapper.eq(Order::getStatus, status);
        }
        queryWrapper.orderByDesc(Order::getCreatedAt);

        IPage<Order> resultPage = orderMapper.selectPage(pageParam, queryWrapper);

        // 转换为OrderVO列表
        List<OrderVO> orderVOList = resultPage.getRecords().stream()
                .map(order -> {
                    OrderVO vo = OrderVO.fromOrder(order);

                    // 获取商品信息
                    Product product = productMapper.selectById(order.getProductId());
                    if (product != null) {
                        vo.setProductName(product.getName());

                        // 从商品图片表获取主图
                        LambdaQueryWrapper<ProductImages> imageQueryWrapper = new LambdaQueryWrapper<>();
                        imageQueryWrapper.eq(ProductImages::getProductId, product.getId())
                                .eq(ProductImages::getIsMain, 1) // 获取主图（isMain=1）
                                .or()
                                .eq(ProductImages::getProductId, product.getId())
                                .orderByAsc(ProductImages::getSortOrder) // 如果没有主图，获取排序最靠前的图片
                                .last("LIMIT 1"); // 只获取一张图片

                        ProductImages mainImage = productImageMapper.selectOne(imageQueryWrapper);
                        if (mainImage != null) {
                            vo.setProductImageUrl(mainImage.getImageUrl());
                        }
                    }

                    // 获取买家信息
                    User buyer = userMapper.selectById(order.getBuyerId());
                    if (buyer != null) {
                        vo.setBuyerName(buyer.getNickname());
                        vo.setBuyerAvatar(buyer.getAvatar());
                    }

                    // 获取评价信息
                    LambdaQueryWrapper<OrderReview> reviewQueryWrapper = new LambdaQueryWrapper<>();
                    reviewQueryWrapper.eq(OrderReview::getOrderId, order.getId());
                    OrderReview review = orderReviewMapper.selectOne(reviewQueryWrapper);

                    // 设置买家评价
                    if (review != null) {
                        vo.setBuyerReview(OrderVO.OrderReviewVO.fromOrderReview(review));
                    } else {
                        // 买家暂无评价，设置为空
                        vo.setBuyerReview(null);
                    }

                    // 设置卖家评价（由于当前系统可能只有买家评价，这里提供一个空的评价）
                    vo.setSellerReview(null); // 默认暂无卖家评价

                    return vo;
                })
                .collect(Collectors.toList());

        Page<OrderVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
        voPage.setRecords(orderVOList);

        // 保存到缓存
        redisTemplate.opsForValue().set(cacheKey, voPage, CACHE_ORDER_EXPIRE, TimeUnit.MINUTES);

        return voPage;
    }

    @Override
    public Order getOrderDetail(Long orderId, Long userId) {
        // 构建缓存键
        String cacheKey = CACHE_ORDER_PREFIX + orderId;

        // 尝试从缓存获取
        Object cachedOrder = redisTemplate.opsForValue().get(cacheKey);
        if (cachedOrder != null) {
            log.info("从缓存获取订单详情: {}", cacheKey);
            return (Order) cachedOrder;
        }

        // 从数据库获取订单
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new ResourceNotFoundException("订单不存在");
        }

        // 验证用户权限
        if (!order.getBuyerId().equals(userId) && !order.getSellerId().equals(userId)) {
            throw new ForbiddenException("无权查看此订单");
        }

        // 保存到缓存
        redisTemplate.opsForValue().set(cacheKey, order, CACHE_ORDER_EXPIRE, TimeUnit.MINUTES);

        return order;
    }

    @Override
    public boolean confirmReceipt(Long orderId, Long userId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new ResourceNotFoundException("订单不存在");
        }

        // 验证用户是订单的买家
        if (!order.getBuyerId().equals(userId)) {
            throw new ForbiddenException("只有买家可以确认收货");
        }

        // 验证订单状态为待收货
        if (order.getStatus() != 1) {
            throw new BadRequestException("订单状态异常，无法确认收货");
        }

        // 更新订单状态为已完成
        order.setStatus(4); // 假设2表示已完成
        order.setCompletionTime(LocalDateTime.now());
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.updateById(order);

        // 清除订单相关缓存
        clearOrderCache(orderId);
        clearBuyerOrdersCache(userId);
        clearSellerOrdersCache(order.getSellerId());

        return true;
    }

    @Override
    public boolean cancelOrder(Long orderId, Long userId, String reason) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new ResourceNotFoundException("订单不存在");
        }

        // 验证用户是订单的买家或卖家
        if (!order.getBuyerId().equals(userId) && !order.getSellerId().equals(userId)) {
            throw new ForbiddenException("无权取消此订单");
        }

        // 验证订单状态可取消（只能取消待交易的订单）
        if (order.getStatus() != 1) {
            throw new BadRequestException("订单状态异常，无法取消");
        }

        // 更新订单状态为已取消
        order.setStatus(3); // 假设3表示已取消
        order.setRemark(reason);
        log.info("订单{}被用户{}取消", orderId, userId);
        order.setCancelTime(LocalDateTime.now());
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.updateById(order);

        // 将商品状态恢复为在售
        Product product = productMapper.selectById(order.getProductId());
        if (product != null) {
            product.setStatus(1); // 1表示在售
            productMapper.updateById(product);
        }

        // 清除订单相关缓存
        clearOrderCache(orderId);
        clearBuyerOrdersCache(order.getBuyerId());
        clearSellerOrdersCache(order.getSellerId());

        return true;
    }

    @Override
    public OrderReview createOrderReview(OrderReviewDTO reviewDTO) {
        Order order = orderMapper.selectById(reviewDTO.getOrderId());
        if (order == null) {
            throw new ResourceNotFoundException("订单不存在");
        }

        // 验证用户是订单的买家
        if (!order.getBuyerId().equals(reviewDTO.getBuyerId())) {
            throw new ForbiddenException("只有买家可以评价订单");
        }

        // 检查是否已评价
        if (order.getIsReviewed()) {
            throw new BadRequestException("该订单已评价");
        }

        // 创建评价
        OrderReview review = new OrderReview();
        review.setOrderId(reviewDTO.getOrderId());
        review.setBuyerId(reviewDTO.getBuyerId());
        review.setSellerId(order.getSellerId());
        review.setProductId(order.getProductId());
        review.setContent(reviewDTO.getContent());
        review.setRatingScore(reviewDTO.getRatingScore());
        review.setCreditScore(reviewDTO.getCreditScore());
        review.setCreatedAt(LocalDateTime.now());

        // 保存评价
        orderReviewMapper.insert(review);

        // 更新订单为已评价且已完成
        order.setIsReviewed(true);
        order.setStatus(2); // 评价后订单状态改为已完成
        order.setCompletionTime(LocalDateTime.now());
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.updateById(order);

        // 更新用户评分（假设有这样的逻辑）
        updateUserRating(order.getSellerId(), reviewDTO.getCreditScore());

        // 清除订单相关缓存
        clearOrderCache(reviewDTO.getOrderId());
        clearOrderReviewCache(reviewDTO.getOrderId());
        clearBuyerOrdersCache(reviewDTO.getBuyerId());
        clearSellerOrdersCache(order.getSellerId());

        return review;
    }

    @Override
    public OrderReview getOrderReview(Long orderId) {
        // 构建缓存键
        String cacheKey = CACHE_ORDER_REVIEW_PREFIX + orderId;

        // 尝试从缓存获取
        Object cachedReview = redisTemplate.opsForValue().get(cacheKey);
        if (cachedReview != null) {
            log.info("从缓存获取订单评价: {}", cacheKey);
            return (OrderReview) cachedReview;
        }

        // 从数据库获取
        LambdaQueryWrapper<OrderReview> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderReview::getOrderId, orderId);
        OrderReview review = orderReviewMapper.selectOne(queryWrapper);

        // 保存到缓存
        if (review != null) {
            redisTemplate.opsForValue().set(cacheKey, review, CACHE_ORDER_EXPIRE, TimeUnit.MINUTES);
        }

        return review;
    }

    private String generateOrderNo() {
        // 简单生成订单号：时间戳 + 4位随机数
        long timestamp = System.currentTimeMillis();
        int random = new Random().nextInt(10000);
        return timestamp + String.format("%04d", random);
    }

    private void updateUserRating(Long userId, Integer newScore) {
        // 更新用户评分的逻辑，这里简化处理
    }

    /**
     * 清除订单缓存
     */
    private void clearOrderCache(Long orderId) {
        if (orderId == null) {
            return;
        }

        log.info("清除订单缓存: {}", orderId);
        String cacheKey = CACHE_ORDER_PREFIX + orderId;
        redisTemplate.delete(cacheKey);
    }

    /**
     * 清除订单评价缓存
     */
    private void clearOrderReviewCache(Long orderId) {
        if (orderId == null) {
            return;
        }

        log.info("清除订单评价缓存: {}", orderId);
        String cacheKey = CACHE_ORDER_REVIEW_PREFIX + orderId;
        redisTemplate.delete(cacheKey);
    }

    /**
     * 清除买家订单列表缓存
     */
    private void clearBuyerOrdersCache(Long buyerId) {
        if (buyerId == null) {
            return;
        }

        log.info("清除买家订单列表缓存: {}", buyerId);
        String pattern = CACHE_ORDER_BUYER_PREFIX + buyerId + "*";
        redisTemplate.keys(pattern).forEach(key -> {
            redisTemplate.delete(key);
        });
    }

    /**
     * 清除卖家订单列表缓存
     */
    private void clearSellerOrdersCache(Long sellerId) {
        if (sellerId == null) {
            return;
        }

        log.info("清除卖家订单列表缓存: {}", sellerId);
        String pattern = CACHE_ORDER_SELLER_PREFIX + sellerId + "*";
        redisTemplate.keys(pattern).forEach(key -> {
            redisTemplate.delete(key);
        });
    }
}